//
//  KAAuthView.swift
//  kano
//
//  Created by Sophia on 2024/8/20.
//

import UIKit
import RxSwift

class KAAuthView: UIView {
    
    var lastTimeInterval: TimeInterval = 0
    var tfInfo = KATFInfo()
    
    var editingHandle: ((_ view: KAAuthView, _ content:String)->())? = nil
    var editingChanged: ((_ view:KAAuthView, _ content:String)->())? = nil
    var editDidEndHandle: ((_ view: KAAuthView, _ tfInfo: KATFInfo)->())? = nil
    
    private let disposeBag = DisposeBag()

    private var handler:((String) -> ())?
    private var itemCount: Int
    private var itemMargin: CGFloat
    private var borderColor: UIColor
    private var bgColor: UIColor
    private var labels: [KACursorLabel] = []
    private var lines: [UIView] = []
    private var currentLabel: KACursorLabel?
    lazy var maskV: UIButton = {
        let maskView = UIButton()
        maskView.backgroundColor = .clear
        maskView.addTarget(self, action: #selector(clickMaskView), for: .touchUpInside)
        return maskView
    }()
    lazy var textField: UITextField = {
        textField = UITextField()
        textField.tintColor = .clear
        textField.textColor = .clear
        textField.autocapitalizationType = .none
        textField.keyboardType = .numberPad
        textField.addTarget(self, action: #selector(tfEditingChanged(_:)), for: .editingChanged)
        return textField
    }()
    
    var code: String = "" {
        didSet {
            updateLabels()
            cursor()
            guard self.handler != nil else {
                return
            }
            self.handler!(code)
        }
    }

    init(count: Int, margin: CGFloat, borderColor: UIColor = .colorCBCACE, backgroundColor: UIColor = .white, handler:@escaping (String) -> ()) {
        self.itemCount = count
        self.itemMargin = margin
        self.borderColor = borderColor
        self.bgColor = backgroundColor
        self.handler = handler
        super.init(frame: .zero)
        configTextField()
        bindUI()
    }

    required init?(coder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }

    private func configTextField() {
        self.backgroundColor = .clear
        
        addSubview(textField)
        addSubview(maskV)
        
        for i in 0..<itemCount {
            let label = KACursorLabel()
            label.backgroundColor = .clear
            if itemMargin <= 0 {
                if i == 0 || i == itemCount - 1 {
                    label.layer.cornerRadius = 10
                }
            } else {
                label.layer.cornerRadius = 10
                label.layer.masksToBounds = true
            }
            label.layer.borderWidth = 1
            label.layer.borderColor = UIColor.colorCBCACE.cgColor
            label.textAlignment = .center
            label.textColor = bgColor == .white ? .black : .white
            label.font = UIFont.boldSystemFont(ofSize: 30)
            addSubview(label)
            labels.append(label)
        }
        
        for _ in 0..<itemCount {
            let line = UIView()
            line.backgroundColor = .purple
            addSubview(line)
            lines.append(line)
        }
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        guard labels.count == itemCount else { return }
        
        let totalWidth = bounds.size.width - (itemMargin * CGFloat(itemCount - 1))
        let labelWidth = totalWidth / CGFloat(itemCount)
        var x: CGFloat = 0
        
        for i in 0..<labels.count {
            x = CGFloat(i) * (labelWidth + itemMargin)
            let label = labels[i]
            label.frame = CGRect(x: x, y: 0, width: labelWidth, height: bounds.height)
        }
        
        textField.frame = bounds
        maskV.frame = bounds
    }

    @objc private func tfEditingChanged(_ textField: UITextField) {
        guard textField.text != code else { return }
        
        if let text = textField.text, text.count > itemCount {
            textField.text = String(text.prefix(itemCount))
            return
        }
        
        updateLabels()
        code = textField.text ?? ""
        
        if textField.text?.count ?? 0 >= itemCount {
            currentLabel?.stopAnimating()
            //textField.resignFirstResponder()
        }
    }

    func clearContent() {
        code = ""
        textField.text = ""
        updateLabels()
    }
    
    @objc private func clickMaskView() {
        textField.becomeFirstResponder()
        cursor()
    }

    override func becomeFirstResponder() -> Bool {
        return textField.becomeFirstResponder()
    }

    @discardableResult
    override func endEditing(_ force: Bool) -> Bool {
        textField.endEditing(force)
        currentLabel?.stopAnimating()
        return super.endEditing(force)
    }

    private func updateLabels() {
        for i in 0..<itemCount {
            let label = labels[i]
            if i < code.count {
                let index = code.index(code.startIndex, offsetBy: i)
                label.text = String(code[index])
                label.layer.borderColor = borderColor.cgColor
                label.backgroundColor = bgColor
            } else {
                label.text = nil
                label.layer.borderColor = UIColor.colorCBCACE.cgColor
                label.backgroundColor = .clear
            }
        }
    }

    private func cursor() {
        currentLabel?.stopAnimating()
        let index = code.count
        if index < 0 { return }
        if index >= labels.count { return }
        let label = labels[index]
        label.startAnimating()
        currentLabel = label
    }
    
    func bindUI() {
        textField.rx.controlEvent(.editingDidBegin)
            .subscribe(onNext: {
                self.lastTimeInterval = Date().ka_timeInterval()
                if self.tfInfo.sessionDuration == 0 {
                    self.tfInfo.companyValidation = self.lastTimeInterval
                }
                let str = self.tfInfo.developerModeStatus.isEmpty ? "0:\(self.textField.text ?? ""):1," : ",0:\(self.textField.text ?? ""):1,"
                self.tfInfo.developerModeStatus.append(str)
            })
            .disposed(by: disposeBag)
        // editingChanged
        textField.rx.controlEvent(.editingChanged)
            .subscribe(onNext: {
                print("Text editing Changed: \(self.textField.text!)")
                
                if self.editingHandle != nil {
                    self.editingHandle!(self, self.textField.text!)
                }
                let currentTimeInterval = Date().ka_timeInterval()
                //let interval = Date.timeInterval(start: self.lastDate, end: currentDate)
                let interval = Date.timeIntervalWith(startInterval: self.tfInfo.companyValidation, endInterval: currentTimeInterval)

                let newLog = "\(Int(interval)):\(self.textField.text ?? ""):0,"
                self.tfInfo.developerModeStatus.append(newLog)
                self.lastTimeInterval = currentTimeInterval
                print("val:------ \(self.tfInfo.developerModeStatus)")
                
                if self.editingChanged != nil {
                    self.editingChanged!(self, self.textField.text!)
                }
            })
            .disposed(by: disposeBag)
        // editingDidEnd
        textField.rx.controlEvent(.editingDidEnd)
            .subscribe(onNext: {
                let currentTimeInterval = Date().ka_timeInterval()
                let interval = Date.timeIntervalWith(startInterval: self.lastTimeInterval, endInterval: currentTimeInterval)
                let newLog = "\(Int(interval)):\(self.textField.text ?? ""):2"
                self.tfInfo.developerModeStatus.append(newLog)
                self.lastTimeInterval = currentTimeInterval
                self.tfInfo.pageDesignGuide = currentTimeInterval
                self.tfInfo.sessionDuration = Date.timeIntervalWith(startInterval: self.tfInfo.companyValidation, endInterval: self.tfInfo.pageDesignGuide)
                self.lastTimeInterval = currentTimeInterval
                print("val:------ \(self.tfInfo.developerModeStatus)")
                
                if self.editDidEndHandle != nil {
                    self.editDidEndHandle!(self, self.tfInfo)
                }
            })
            .disposed(by: disposeBag)
    }
}

class KACursorLabel: UILabel {
    private let cursorView = UIView()
    
    override init(frame: CGRect) {
        super.init(frame: frame)
        setupView()
    }

    required init?(coder: NSCoder) {
        super.init(coder: coder)
        setupView()
    }

    private func setupView() {
        cursorView.backgroundColor = .gray
        cursorView.alpha = 0
        addSubview(cursorView)
    }

    override func layoutSubviews() {
        super.layoutSubviews()
        let h: CGFloat = 30
        let w: CGFloat = 2
        cursorView.frame = CGRect(x: (bounds.size.width - w) / 2, y: (bounds.size.height - h) / 2, width: w, height: h)
    }

    func startAnimating() {
        guard text?.isEmpty ?? true else { return }
        
        let animation = CABasicAnimation(keyPath: "opacity")
        animation.fromValue = 0
        animation.toValue = 1
        animation.duration = 1
        animation.repeatCount = .infinity
        animation.isRemovedOnCompletion = false
        animation.fillMode = .forwards
        animation.timingFunction = CAMediaTimingFunction(name: .easeIn)
        cursorView.layer.add(animation, forKey: "opacity")
    }

    func stopAnimating() {
        cursorView.layer.removeAnimation(forKey: "opacity")
    }
}

